package com.hj.ipproxy.service;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.hj.ipproxy.bean.HttpEntity;
import com.hj.ipproxy.bean.ProxyIp;
import com.hj.ipproxy.config.ConfigrurationMgr;
import com.hj.ipproxy.handler.FetchIpHandler;
import com.hj.ipproxy.httpclient.TcpType;
import com.hj.ipproxy.util.ProxyIpUtil;
import com.hj.tools.FileUtil;
import com.hj.tools.StringUtil;
import com.hj.tools.list.CollnectionUtil;

public class ProxyIpServiceImpl implements ProxyIpService{
	// 有效IP
	private final Set<ProxyIp> validityIps = new HashSet<ProxyIp>();
	// 合格IP
	private final Set<ProxyIp> filterIps =new HashSet<ProxyIp>();
	
	//　白名单
	private final Set<String> whiteList = new HashSet<String>();
	// 黑名单
	private final Set<String> blackList = new HashSet<String>();
	private Map<String, FetchIpHandler> handlers;
	private int total = 0;
	// handler锁
	private final Object HANDLERFINISHLOCK = new Object();
	
	/*单例模式*/
	private ProxyIpServiceImpl(){handlers = ConfigrurationMgr.getFetchHandler();}
	private static ProxyIpServiceImpl proxyIpSev = new ProxyIpServiceImpl();
	public static ProxyIpServiceImpl getInstance(){
		return proxyIpSev;
	}
	
	/**
	 * 获取代理IP集
	 */
	public Set<ProxyIp> getProxyIps(){
		for (final FetchIpHandler h : handlers.values()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					h.fetchProxyIp(proxyIpSev);
				}
			}).start();
		}
		System.out.println("获取代理IP,等待被唤醒....");
		synchronized (HANDLERFINISHLOCK) {
			try {
				HANDLERFINISHLOCK.wait();
			} catch (InterruptedException e) {
				System.err.println("获取代理IP,唤醒异常："+e.getMessage());
			}
		}
		return Collections.unmodifiableSet(validityIps);
	}
	
	/**
	 * 过滤合格IP集
	 */
	public Set<ProxyIp> filterProxyIps(long mis){
		try {
			if (CollnectionUtil.isEmpty(validityIps)) {
				getProxyIps();
			}
			for (ProxyIp pi : validityIps) {
				// 过滤合格IP
				HttpEntity ht = proxyIpSev.checkProxyIp(pi.getIp(), pi.getPort());
				if (ht.isSuccess()) {
					filterIps.add(pi);
					addBlackList(pi.getIp()+":"+pi.getPort());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return CollnectionUtil.filterSet(filterIps);
	}
	
	public static boolean filterProxyIps(long mis, String ip, int port){
		try {
			HttpEntity ht = proxyIpSev.checkProxyIp(ip, port);
			if (ht.isSuccess() && ht.getRespTime()<=mis) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 检查当前代理IP是否还有效
	 * @param ht
	 */
	public HttpEntity checkProxyIp(String ip, int port){
		//System.out.println("检查代理ＩＰ---"+ip+":"+port);
		HttpEntity ht = new HttpEntity(ConfigrurationMgr.getValidateUrl(), ip, port);
		ht.setTcpType(TcpType.GET_HTTP_PROXY);
		ht.setCharset("GB2312");
		if (ht.send()) {
			try {
				String body = ht.getBody();
				String proxyIpInfo = StringUtil.match(body, ">(您的(IP|ip)地址是.+?)<")[1];
				//System.out.println("当前代理IP信息---"+ proxyIpInfo);
				String newIp = StringUtil.match(proxyIpInfo, "\\[(.*)\\]")[1];
				//|| !newIp.equals(HttpClientManager.getMyIp())
				if (newIp.matches(".*"+ip+".*")) {
					String addrs = StringUtil.match(proxyIpInfo, "自：(.+)")[1];
					ht.setAddrs(addrs);
				}else{
					ht.setBody(null); //表示代理IP无效
				}
			} catch (Exception e) {
				ht.setBody(null); //表示代理IP无效
				System.err.println("检查代理IP异常："+e.getMessage());
			}
		}
		return ht;
	}
	
	/**
	 * 把代理IP保存到本地硬盘
	 * @param filePath
	 */
	public void saveIp(String filePath){
		if (CollnectionUtil.isNotEmpty(whiteList)) {
			StringBuffer text = new StringBuffer();
			for (String str : whiteList) {
				text.append(str).append(ProxyIpUtil.NEW_LINE);
			}
			FileUtil.createAndWriteFile(filePath, text.toString());
		}
	}
	
	/**
	 * 添加到白名单
	 */
	public void addWhiteList(String ip){
		whiteList.add(ip);
	}
	
	/**
	 * 清空白名单
	 */
	public void clearWhiteList(){
		whiteList.clear();
	}
	
	/**
	 * IP是否存在白名单内
	 * @param ip
	 */
	public boolean existsWhiteList(String ip){
		return whiteList.contains(ip);
	}
	
	/**
	 * 添加到黑名单
	 */
	public void addBlackList(String ip){
		whiteList.remove(ip);
		filterIps.remove(ip);
		blackList.add(ip);
	}
	
	/**
	 * IP是否存在黑名单内
	 * @param ip
	 */
	public boolean existsBlackList(String ip){
		return blackList.contains(ip);
	}
	
	/**
	 * 清空黑名单
	 */
	public void clearBlackList(){
		blackList.clear();
	}

	/**
	 * 移出黑名单
	 */
	public void rmBlackList(String ip) {
		blackList.remove(ip);
	}
	
	public synchronized void addValidityIp(ProxyIp ip){
		validityIps.add(ip);
	}
	
	/**
	 * 一个handler完成了就来打个标签
	 */
	public void finishDoTag(){
		synchronized(HANDLERFINISHLOCK){
			total++;
			System.err.println(Thread.currentThread().getName()+":签到("+total+")");
			if (total == ConfigrurationMgr.getHandlerTotal()) {
				HANDLERFINISHLOCK.notify();
			}
		}
	}

	public static String getByProxy(String url, String ip, int port) {
		HttpEntity hts = new HttpEntity(url, ip, port);
		hts.setTcpType(TcpType.GET_HTTPS_PROXY);
		hts.setReadtimeout(800);;
		hts.setConnecttimerout(500);
		hts.send();
		return hts.getBody();
	}
}
